import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  ScrollView,
  FlatList,
  TextInput,
  Platform,
  Alert,
  PermissionsAndroid,
  ToastAndroid,
  Switch,
  Button
} from 'react-native';
// import { SafeAreaProvider } from 'react-native-safe-area-context';
import Slider from '@react-native-community/slider'
import { SafeAreaView } from 'react-navigation'
import { connect } from 'react-redux'
import HeaderButtons, { Item } from 'react-navigation-header-buttons'
import BleModule from './BleModule';
import { ADD_DEVICE } from './reducer/connectedDevice'
// import { SvgUri } from 'react-native-svg';
import { SvgXml } from 'react-native-svg';
import AsyncStorage from '@react-native-async-storage/async-storage';
// import wenhao3 from './icon/wenhao3.svg'
//确保全局只有一个BleManager实例，BleModule类保存着蓝牙的连接信息
global.BluetoothManager = new BleModule();  
@connect(({ connectedDevice }) => ({
    connectedDevices: connectedDevice.list
  }))
 
export default class App extends Component {
    constructor(props) {
        super(props);   
        this.state={
            scaning:false,
            isConnected:false,
            text:'',
            writeData:'',
            receiveData:'',
            readData:'',
            data:[],
            isMonitoring:false,
            sliderval:0,
            trueSwitchIsOn:true,
            falseSwitchIsOn:false
        }

        this._checkState()
        this.bluetoothReceiveData = [];  //蓝牙接收的数据缓存
        this.deviceMap = new Map();
    }
    
    static navigationOptions = ({navigation,navigationOptions})=> {
        const {params} = navigation.state;
        const wenhao3 = `<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#333333" d="M632.064 305.792c-29.056-26.24-66.56-38.144-114.688-38.144-53.568 0-94.848 15.68-124.672 47.872-29.824 30.656-43.584 71.04-43.584 121.856h58.88c0-35.84 8.384-62.784 24.448-83.712 17.6-23.936 45.12-35.904 82.56-35.904 31.36 0 55.872 8.192 72.704 25.408 16.064 15.68 25.216 38.144 25.216 67.328 0 20.16-7.616 38.848-22.144 57.6-4.608 5.952-12.992 14.144-25.216 26.112-39.808 35.2-64.256 62.848-75.008 84.48-9.152 17.984-12.992 38.912-12.992 62.848v17.216h59.648v-16.448c0-19.456 4.608-37.376 13.824-53.12 7.616-12.672 18.304-26.176 35.2-39.68 32.832-28.352 52.736-47.04 60.352-56 18.368-23.936 28.288-52.352 28.288-85.248-1.472-43.392-15.296-77.824-42.816-102.464z m-125.44 403.84a42.624 42.624 0 0 0-32.128 12.672 38.144 38.144 0 0 0-12.992 30.72c0 12.672 3.84 22.4 12.992 31.36a45.632 45.632 0 0 0 32.128 12.736c13.056 0 22.976-4.48 32.128-12.8 9.216-8.192 12.992-17.92 12.992-31.36a40.704 40.704 0 0 0-12.992-30.656 42.624 42.624 0 0 0-32.128-12.736z"  /></svg>`

        return {
            headerTitle: 'J_M',
            headerTitleStyle:{
                flex: 1,
                textAlign: 'center'
            },
            headerRight: () => 
                <TouchableOpacity onPress={()=>navigation.push('ToFAQ')} >
                    <Text style={{width:'100%',height:'100%'}}>
                        <SvgXml width="55" height="55" xml={wenhao3} />                        
                    </Text>
                     
                    {/* <Text style={{fontSize:24,marginRight:10,backgroundColor:'red'}} >?</Text> */}
                </TouchableOpacity>
                //SvgXml内必须设置成像素？百分数无效。其他地方不同//
                ,
            headerLeft: () => 
            <View>
                <Text>
                    {/* <SvgXml width="50" height="50" xml={wenhao3} /> */}
                </Text>                
            </View>
        }
    }
    getData = async () => {
        try {
          const jsonValue = await AsyncStorage.getItem('bluenames')
          return jsonValue != null ? JSON.parse(jsonValue) : null;
        } catch(e) {
          // error reading value
          console('src/index/getdata has error')
          return null;
        }
      }
    storeData = async (value) => {
        // console.log(value,'2222222222222222222')
        try {
            // AsyncStorage.removeItem('bluenames') ;
          var bluenames = await this.getData()
          const bluename = value.item.localName || value.item.name;
          const seen = [];
          const jsonValue = JSON.stringify(value, function(key, val) {
            if (typeof val === "object") {
                 if (seen.indexOf(val) >= 0) return;
                 seen.push(val)
                // seen.push({key : val});
                // console.log('66666666666666666',typeof val,val)
             }
             return val;
         })
          await AsyncStorage.setItem(bluename, jsonValue)
         
        //   console.log(bluenames,seen,'222222222222223333333',jsonValue)
          if (bluenames == null) {var bluenames =Array();}

            //   for(let i = 0; i < bluenames.length; i++ ){
            //     // if(bluenames.i.item != undefined){
            //     // bluetooth[i] = bluenames[i];
            //     // } 
            //     // else {
            //     //     const bluenames = {};
            //     // }
            //     console.log(bluenames,'6666666666666');
            //   }
          
        //   console.log(bluenames,'1111111111',bluename)
          bluenames.push(bluename)
        //   bluetooth.map(
        //       (item2,key2) => {
        //         bluenames[key2] = item2;
        //       }
        //   )
          const bluekey = JSON.stringify(bluenames)
          await AsyncStorage.setItem('bluenames', bluekey)
        } catch (e) {
          // saving error
          console.log(e,'1111111211111111')
        }
      }

    show(data) {
        ToastAndroid.show(data,ToastAndroid.SHORT)
    }
    async requestLocationPermission() {
        try {
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                {
                    //第一次请求拒绝后提示用户你为什么要这个权限
                    'title': '我要地址查询权限',
                    'message': '没权限我不能工作，同意就好了'
                }
            )
  
            if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了地址查询权限")
            } else {
                this.show("获取地址查询失败")
            }
        } catch (err) {
            this.show(err.toString())
        }
    }
    async requestReadPermission() {
        try {
            //返回string类型
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
                {
                    //第一次请求拒绝后提示用户你为什么要这个权限
                    'title': '我要读写权限',
                    'message': '没权限我不能工作，同意就好了'
                }
            )
            if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了读写权限")
            } else {
                this.show("获取读写权限失败")
            }
        } catch (err) {
            this.show(err.toString())
        }
    }  
    async requestAllPermission() {
        try {
            //返回string类型
            const granted = await PermissionsAndroid.requestMultiple([
                PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
                PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
                PermissionsAndroid.PERMISSIONS.CAMERA,
            ]);
            if (granted['android.permission.ACCESS_FINE_LOCATION'] === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了定位权限")
            } else {
                this.show("获取定位权限失败")
            }
            if (granted['android.permission.WRITE_EXTERNAL_STORAGE'] === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了读写权限")
            } else {
                this.show("获取读写权限失败")
            }
            if (granted['android.permission.RECORD_AUDIO'] === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了麦克风权限")
            } else {
                this.show("获取麦克风权限失败")
            }
            
            if (granted['android.permission.CAMERA'] === PermissionsAndroid.RESULTS.GRANTED) {
                this.show("你已获取了相机权限")
            } else {
                this.show("获取相机权限失败")
            }
        } catch (err) {
            this.show(err.toString())
        }
    }  
    _checkState = () => {
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((data)=>{
            // this.show("是否获取LOCATION权限"+data)
            if (!data) {          
                // this.requestLocationPermission()  //单独申请定位权限的方法
                this.requestAllPermission()
            }
        }).catch((err)=>{
            this.show(err.toString())
        })
        // console.log(PermissionsAndroid.RESULTS.GRANTED)
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,).then((data)=>{
            // this.show("我要读写权限 "+data)
            if (!data) {          
                this.requestAllPermission()
            }
        }).catch((err)=>{
            this.show(err.toString())
        })
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,).then((data)=>{
            // this.show("我要麦克风权限 "+data)
            if (!data) {          
                this.requestAllPermission()
            }
        }).catch((err)=>{
            this.show(err.toString())
        })
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA,).then((data)=>{
            // this.show("我要相机权限 "+data)
            if (!data) {          
                this.requestAllPermission()
            }
        }).catch((err)=>{
            this.show(err.toString())
        })
    //   this.bleManager.state()
    //     .then(state => {
    //       this.setState({
    //         bleState: state
    //       })
    //       if (state === 'PoweredOff') {
    //         this._showAlert()
    //       }
    //     })
    }
    componentDidMount(){
        // 监听蓝牙开关
        this.onStateChangeListener = BluetoothManager.manager.onStateChange((state) => {
            console.log("onStateChange: ", state);
            if(state == 'PoweredOn'){
                this.scan();
            }               
        })
    }     

    componentWillUnmount() {
       BluetoothManager.destroy();
       this.onStateChangeListener && this.onStateChangeListener.remove();
       this.disconnectListener && this.disconnectListener.remove();
       this.monitorListener && this.monitorListener.remove();
    }

    alert(text){
        Alert.alert('提示',text,[{ text:'确定',onPress:()=>{ } }]);
    }

    scan(){
        if(!this.state.scaning) {
            this.setState({scaning:true});
            this.deviceMap.clear();
            BluetoothManager.manager.startDeviceScan(null, null, (error, device) => {                
                if (error) {
                    console.log('startDeviceScan error:',error)
                    if(error.errorCode == 102){
                        this.alert('请打开手机蓝牙后再搜索');
                    }
                    this.setState({scaning:false});   
                }else{
                    console.log(device.id,device.name);
                    this.deviceMap.set(device.id,device); //使用Map类型保存搜索到的蓝牙设备，确保列表不显示重复的设备
                    this.setState({data:[...this.deviceMap.values()]});      
                }              
            })
            this.scanTimer && clearTimeout(this.scanTimer);
            this.scanTimer = setTimeout(()=>{
                if(this.state.scaning){
                   BluetoothManager.stopScan();
                   this.setState({scaning:false});                   
                }                
            },9000)  //9秒后停止搜索
        }else {
            BluetoothManager.stopScan();
            this.setState({scaning:false});
        }
    }
   
    connect(item){        
        const { connectedDevices, dispatch, navigation } = this.props
        if(this.state.scaning){  //连接的时候正在扫描，先停止扫描
            BluetoothManager.stopScan();
            this.setState({scaning:false});
        }
        if(BluetoothManager.isConnecting){
            console.log('当前蓝牙正在连接时不能打开另一个连接进程');
            return;
        }
        let newData = [...this.deviceMap.values()];
        newData[item.index].isConnecting = true;  //正在连接中
        this.setState({data:newData});
        BluetoothManager.connect(item.item.id)
            .then(device=>{
                newData[item.index].isConnecting = false;
                this.setState({data:[newData[item.index]], isConnected:true});
                this.onDisconnect();
            })
            .catch(err=>{
                newData[item.index].isConnecting = false;
                this.setState({data:[...newData]});
                this.alert(err);
            })
        dispatch({
            type: ADD_DEVICE,
            payload: item
            })
        // console.log(item,'3333333333333333')    
        this.storeData(item);
    }

    read=(index)=>{
        BluetoothManager.read(index)
            .then(value=>{
                this.setState({readData:value});
            })
            .catch(err=>{

            })       
    }

    write=(index,type)=>{
        if(this.state.text.length == 0){
            this.alert('请输入消息');
            return;
        }
        BluetoothManager.write(this.state.text,index,type)
            .then(characteristic=>{
                this.bluetoothReceiveData = [];
                this.setState({
                    writeData:this.state.text,
                    text:'',
                })
            })
            .catch(err=>{

            })       
    }

    writeWithoutResponse=(index,type)=>{
        if(this.state.text.length == 0){
            this.alert('请输入消息');
            return;
        }
        BluetoothManager.writeWithoutResponse(this.state.text,index,type)
            .then(characteristic=>{
                this.bluetoothReceiveData = [];
                this.setState({
                    writeData:this.state.text,
                    text:'',
                })
            })
            .catch(err=>{

            })              
    }

    //监听蓝牙数据 
    monitor=(index)=>{
        let transactionId = 'monitor';
        this.monitorListener = BluetoothManager.manager.monitorCharacteristicForDevice(BluetoothManager.peripheralId,
            BluetoothManager.nofityServiceUUID[index],BluetoothManager.nofityCharacteristicUUID[index],
            (error, characteristic) => {
                if (error) {
                    this.setState({isMonitoring:false});
                    console.log('monitor fail:',error);    
                    this.alert('monitor fail: ' + error.reason);      
                }else{
                    this.setState({isMonitoring:true});
                    this.bluetoothReceiveData.push(characteristic.value); //数据量多的话会分多次接收
                    this.setState({receiveData:this.bluetoothReceiveData.join('')})
                    console.log('monitor success',characteristic.value);
                    // this.alert('开启成功'); 
                }

            }, transactionId)
    }  

    //监听蓝牙断开 
    onDisconnect(){        
        this.disconnectListener = BluetoothManager.manager.onDeviceDisconnected(BluetoothManager.peripheralId,(error,device)=>{
            if(error){  //蓝牙遇到错误自动断开
                console.log('onDeviceDisconnected','device disconnect',error);
                this.setState({data:[...this.deviceMap.values()],isConnected:false});
            }else{
                this.disconnectListener && this.disconnectListener.remove();
                console.log('onDeviceDisconnected','device disconnect',device.id,device.name);
            }
        })
    }

    //断开蓝牙连接
    disconnect(){
        BluetoothManager.disconnect()
            .then(res=>{
                this.setState({data:[...this.deviceMap.values()],isConnected:false});
            })
            .catch(err=>{
                this.setState({data:[...this.deviceMap.values()],isConnected:false});
            })     
    }   

    renderItem=(item)=>{
        let data = item.item;
        return(
            <TouchableOpacity
                activeOpacity={0.7}
                disabled={this.state.isConnected?true:false}
                onPress={()=>{this.connect(item)}}
                style={styles.item}>                         
                <View style={{flexDirection:'row'}}>
                    <Text style={{color:'black'}}>{data.name?data.name:''}</Text>
                    <Text style={{color:"red",marginLeft:50}}>{data.isConnecting?'连接中...':''}</Text>
                </View>
                <Text>{data.id}</Text>
               
            </TouchableOpacity>
        );
    }

    renderHeader=()=>{
        const { navigation } = this.props
 
        return(
           <SafeAreaView>
            <View style={{marginTop:20}}>
                <TouchableOpacity 
                    activeOpacity={0.7}
                    style={[styles.buttonView,{marginHorizontal:10,height:40,alignItems:'center'}]}
                    onPress={this.state.isConnected?this.disconnect.bind(this):this.scan.bind(this)}>
                    <Text style={styles.buttonText}>{this.state.scaning?'正在搜索中':this.state.isConnected?'断开蓝牙':'搜索蓝牙'}</Text>
                </TouchableOpacity>
                
                <View style={{marginLeft:10,marginTop:10,width:"100%",flex:1,flexDirection: 'row',justifyContent:'flex-start'}}>

                    <View style={{marginLeft:10,width:"30%"}}>  
                        <Text>{this.state.isConnected?'当前连接的设备':'可连设备'}</Text> 
                    </View>
                    <View style={{width:"70%"}}>
                        <Text style={{width:"80%",textAlign:'right'}}>
                            <Item
                                title="杰曼设备"
                                buttonStyle={{ color: '#1890ff', fontSize: 14}}
                                onPress={() => navigation.push('Device')}
                            />
                            <Item
                                title="杰曼语音"
                                buttonStyle={{ color: '#1890ff', fontSize: 14}}
                                onPress={() => navigation.push('Asr')}
                            />
                            <Item
                                title="杰曼唤醒"
                                buttonStyle={{ color: '#1890ff', fontSize: 14}}
                                onPress={() => navigation.push('Wakeup')}
                            />
                        </Text>
    
                    </View>

                    
                </View>
                <View  style={{justifyContent:'center'}}>
                    <Text style={{textAlign:'center'}}>
                        {this.state.sliderval}
                    </Text>
                </View>
                <Slider
                    style={{width: "100%", height: 40}}
                    minimumValue={0}
                    maximumValue={100}
                    minimumTrackTintColor="#e36209"
                    maximumTrackTintColor="#000000"
                    justifyContent="space-around"
                    onValueChange={(value)=>{this.setState({sliderval:value})}}
                    onSlidingComplete={(value)=>{this.setState({sliderval:value})}}
                    step={2}
                />
            </View>
            <View style={{flexDirection:'row',paddingLeft:20}}>
                <Text style={{marginTop:5}}>第一</Text>
                <Switch
                onValueChange={(value) => this.setState({falseSwitchIsOn: value})}
                style={{marginBottom:20}}
                trackColor={{false: '#b2b2b2', true: '#fc4c00'}}
                value={this.state.falseSwitchIsOn} />
               <Text>第二</Text>
                <Switch
                onValueChange={(value) => this.setState({trueSwitchIsOn: value})}
                value={this.state.trueSwitchIsOn} 
                trackColor={{false: '#ffa67e', true: '#fc4c00'}}/>
                
            </View>
           </SafeAreaView>
                
          
        )
    }

    renderFooter=()=>{
        return(
            <View style={{marginBottom:30}}>
                {this.state.isConnected?
                <View>
                    {this.renderWriteView('写数据(write)：','发送',
                            BluetoothManager.writeWithResponseCharacteristicUUID,this.write)}
                    {this.renderWriteView('写数据(writeWithoutResponse)：','发送',
                            BluetoothManager.writeWithoutResponseCharacteristicUUID,this.writeWithoutResponse,)}
                    {this.renderReceiveView('读取的数据：','读取',
                            BluetoothManager.readCharacteristicUUID,this.read,this.state.readData)}
                    {this.renderReceiveView(`监听接收的数据：${this.state.isMonitoring?'监听已开启':'监听未开启'}`,'开启监听',
                            BluetoothManager.nofityCharacteristicUUID,this.monitor,this.state.receiveData)}
                </View>                   
                :<View style={{marginBottom:20}}></View>
                }        
            </View>
        )
    }

    renderWriteView=(label,buttonText,characteristics,onPress,state)=>{
        if(characteristics.length == 0){
            return null;
        }
        return(
            <View style={{marginHorizontal:10,marginTop:30}} behavior='padding'>
                <Text style={{color:'black'}}>{label}</Text>
                    <Text style={styles.content}>
                        {this.state.writeData}
                    </Text>                        
                    {characteristics.map((item,index)=>{
                        return(
                            <TouchableOpacity 
                                key={index}
                                activeOpacity={0.7} 
                                style={styles.buttonView} 
                                onPress={()=>{onPress(index)}}>
                                <Text style={styles.buttonText}>{buttonText} ({item})</Text>
                            </TouchableOpacity>
                        )
                    })}      
                    <TextInput
                        style={[styles.textInput]}
                        value={this.state.text}
                        placeholder='请输入消息'
                        onChangeText={(text)=>{
                            this.setState({text:text});
                        }}
                    />
            </View>
        )
    }

    renderReceiveView=(label,buttonText,characteristics,onPress,state)=>{
        if(characteristics.length == 0){
            return null;
        }
        return(
            <View style={{marginHorizontal:10,marginTop:30}}>
                <Text style={{color:'black',marginTop:5}}>{label}</Text>               
                <Text style={styles.content}>
                    {state}
                </Text>
                {characteristics.map((item,index)=>{
                    return(
                        <TouchableOpacity 
                            activeOpacity={0.7} 
                            style={styles.buttonView} 
                            onPress={()=>{onPress(index)}} 
                            key={index}>
                            <Text style={styles.buttonText}>{buttonText} ({item})</Text>
                        </TouchableOpacity>
                    )
                })}        
            </View>
        )
    }   

    render () {
        return (
            <View style={styles.container}>  
                <FlatList 
                    renderItem={this.renderItem}
                    keyExtractor={item=>item.id}
                    data={this.state.data}
                    ListHeaderComponent={this.renderHeader}
                    ListFooterComponent={this.renderFooter}
                    extraData={[this.state.isConnected,this.state.text,this.state.receiveData,this.state.readData,this.state.writeData,this.state.isMonitoring,this.state.scaning]}
                    keyboardShouldPersistTaps='handled'
                />            
            </View>
        )
    }
}

const styles = StyleSheet.create({   
    container: {
        flex: 1,
        backgroundColor:'white',
        marginTop:Platform.OS == 'ios'?20:0,
    },
    item:{
        flexDirection:'column',
        borderColor:'rgb(235,235,235)',
        borderStyle:'solid',
        borderBottomWidth:StyleSheet.hairlineWidth,
        paddingLeft:10,
        paddingVertical:8,       
    },
    buttonView:{
        height:30,
        backgroundColor:'rgb(33, 150, 243)',
        paddingHorizontal:10,
        borderRadius:5,
        justifyContent:"center",   
        alignItems:'center',
        alignItems:'flex-start',
        marginTop:10
    },
    buttonText:{
        color:"white",
        fontSize:12,
    },
    content:{        
        marginTop:5,
        marginBottom:15,        
    },
    textInput:{       
		paddingLeft:5,
		paddingRight:5,
		backgroundColor:'white',
		height:50,
        fontSize:16,
        flex:1,
	},
    daohang:{
        fontSize:16,
    }
})



